home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 280_01 / format.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-11  |  10.6 KB  |  524 lines

  1. /* [FORMAT.C of JUGPDS Vol.46]*/
  2. /*
  3. *****************************************************************
  4. *                                *
  5. *    Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  6. *            49-114 Kawauchi-Sanjuunin-machi        *
  7. *            Sendai, Miyagi 980                          *
  8. *            Phone: 0222-61-3219                *
  9. *                                *
  10. *       Modifird by Toshiya Oota   (JUG-CPM No.10)              *
  11. *                   Sakae ko-po 205                 *
  12. *            5-19-6 Hosoda                *
  13. *            Katusikaku Tokyo 124            *
  14. *                                *
  15. *        for MS-DOS Lattice C V3.1J & 80186/V20/V30    *
  16. *                                *
  17. *    Compiler Option: -ccu -k0(1) -ms -n -v -w        *
  18. *                                *
  19. *    Edited & tested by Y. Monma (JUG-CP/M Disk Editor)    *
  20. *            &  T. Ota   (JUG-CP/M Sub Disk Editor)    *
  21. *                                *
  22. *****************************************************************
  23. */
  24.  
  25. /*    format - text formatter 
  26.  
  27. ---------------------------------------------------------------------
  28.  #  dot command  break?  default     function
  29. ---------------------------------------------------------------------
  30.  1  .fi          yes          stat filling
  31.  2  .nf          yes              stop filling
  32.  3  .br n        yes              cause break
  33.  4  .ls n        no       n=1     line spacing is n
  34.  5  .bp n        yes      n=+1    begin page numbered n
  35.  6  .sp n        yes      n=1     space down n lines
  36.  7  .in n        no       n=0     indent n spaces
  37.  8  .rm n        no       n=60    set right margin to n
  38.  9  .ti n        yes      n=0     temporary indent of n
  39. 10  .ce n        yes      n=1     center nextn lines
  40. 11  .ul n        no       n=1     underline words from next n lines
  41. 12  .he          no      empty    header title
  42. 13  .fo          no      empty    footer title
  43. 14  .pl n        no       n=66    set page length to n
  44. ---------------------------------------------------------------------
  45.  
  46. .bp 1
  47. .in 8
  48. .rm 76
  49. .he :        program     format.c                                       #
  50. */
  51.  
  52. #include "stdio.h"
  53. #include "dos.h"
  54. #include "tools.h"
  55. #include "toolfunc.h"
  56.  
  57. #define UNKNOWN 0
  58. #define FI 1
  59. #define NF 2
  60. #define BR 3
  61. #define LS 4
  62. #define BP 5
  63. #define SP 6
  64. #define IN 7
  65. #define RM 8
  66. #define TI 9
  67. #define CE 10
  68. #define UL 11
  69. #define HE 12    /* Header enable */
  70. #define FO 13
  71. #define PL 14
  72.  
  73. #define SQUOTE '\''
  74. #define DQUOTE '"'
  75. #define MINUS '-'
  76. #define COMMAND '.'
  77. #define PAGENUM '#'
  78. #define PAGELEN 66
  79. #define PAGEWIDTH 60
  80. #define MAXOUT 256
  81. #define HUGE 1000
  82. #define INSIZE 256
  83.  
  84.  
  85. int    fill,    /* fill if YES; init = YES            */
  86.     lsval,    /* current line spacing; init = 1        */
  87.     inval,    /* current indent; >= 0; init = 0        */
  88.     rmval,    /* current right margin; init = PAGEWIDTH = 60    */
  89.     tival,    /* current temporary indent; init = 0        */
  90.     ceval,    /* # of lines to center; init = 0        */
  91.     ulval,    /* # of lines to underline; init = 0        */
  92.     curpag,
  93.     newpag,
  94.     lineno,
  95.     plval;
  96.  
  97. int    m1val, m2val, m3val, m4val, bottom;
  98.  
  99. char    __header[MAXLINE], __footer[MAXLINE], *header, *footer;
  100.  
  101. int    outp, outw, outwds, dir;
  102. char    outbuf[(MAXOUT+1)];
  103. /*
  104. .bp
  105. */
  106.  
  107. void init(),Comand(),Text(),LineSpace(),brk(),GetTitle(),pfoot(),phead();
  108. void putchr(),skip(),LeadBlank(),PutWord(),spread(),PutTitle(),put();
  109.  
  110. void main(argc, argv)
  111. int    argc;
  112. char     **argv;
  113. {
  114. char inbuf[MAXLINE], *line;
  115.  
  116.     if (argc < 2)
  117.         error("FRM999 Usage: format <infile >outfile");
  118.     init();
  119.     line = inbuf;
  120.     while (getlin(line, MAXLINE) > 0)
  121.         if (*line == COMMAND)
  122.             Comand(line);
  123.         else
  124.             Text(line);
  125.     if (lineno > 0)
  126.         LineSpace(HUGE);
  127. }
  128.  
  129. /*    comand - perform formatting command
  130. .bp
  131. */
  132. void Comand(line)
  133. char *line;
  134. {
  135. int ctyp, argtyp, val, spval;
  136.  
  137.     if ((ctyp = ComandTyp(line)) == UNKNOWN)
  138.         return;
  139.     val = GetArgVal(line, &argtyp);
  140.     switch (ctyp) {
  141.     case FI :
  142.         brk();
  143.         fill = YES;
  144.         break;
  145.     case NF :
  146.         brk();
  147.         fill = NO;
  148.         break;
  149.     case BR :
  150.         brk();
  151.         break;
  152.     case LS :
  153.         lsval = set(&lsval, val, argtyp, 1, 1, HUGE);
  154.         break;
  155.     case BP :
  156.         if (lineno > 0)
  157.             LineSpace(HUGE);
  158.         curpag = set(&curpag, val, argtyp, curpag+1, -HUGE, HUGE);
  159.         newpag = curpag;
  160.         break;
  161.     case SP :
  162.         spval = set(&spval, val, argtyp, 1, 0, HUGE);
  163.         LineSpace(spval);
  164.         break;
  165.     case IN :
  166.         inval = set(&inval, val, argtyp, 0, 0, rmval-1);
  167.         tival = inval;
  168.         break;
  169.     case RM :
  170.         rmval = set(&rmval, val, argtyp, PAGEWIDTH, tival+1, HUGE);
  171.         break;
  172.     case TI :
  173.         brk();
  174.         tival = set(&tival, val, argtyp, 0, 0, rmval);
  175.         break;
  176.     case CE :
  177.         brk();
  178.         ceval = set(&ceval, val, argtyp, 1, 0, HUGE);
  179.         break;
  180.     case UL :
  181.         ulval = set(&ulval, val, argtyp, 0, 1, HUGE);
  182.         break;
  183.     case HE :
  184.         GetTitle(line, header);
  185.         break;
  186.     case FO :
  187.         GetTitle(line, footer);
  188.         break;
  189.     case PL :
  190.         plval = set(&plval, val, argtyp, PAGELEN,
  191.             m1val + m2val + m3val + m4val + 1, HUGE);
  192.         bottom = plval - m3val - m4val;
  193.         break;
  194.     }
  195. }
  196.  
  197. ComandTyp(line)
  198. char *line;
  199. {
  200. char cmd[3];
  201.     ++line;    cmd[0] = toupper(*line);
  202.     ++line;    cmd[1] = toupper(*line);
  203.     cmd[2] = '\0';
  204.     if (!strcmp(cmd, "FI"))
  205.         return(FI);
  206.     else if (!strcmp(cmd, "NF"))
  207.         return(NF);
  208.     else if (!strcmp(cmd, "BR"))
  209.         return(BR);
  210.     else if (!strcmp(cmd, "LS"))
  211.         return(LS);
  212.     else if (!strcmp(cmd, "BP"))
  213.         return(BP);
  214.     else if (!strcmp(cmd, "IN"))
  215.         return(IN);
  216.     else if (!strcmp(cmd, "RM"))
  217.         return(RM);
  218.     else if (!strcmp(cmd, "TI"))
  219.         return(TI);
  220.     else if (!strcmp(cmd, "CE"))
  221.         return(CE);
  222.     else if (!strcmp(cmd, "UL"))
  223.         return(UL);
  224.     else if (!strcmp(cmd, "HE"))
  225.         return(HE);
  226.     else if (!strcmp(cmd, "FO"))
  227.         return(FO);
  228.     else if (!strcmp(cmd, "PL"))
  229.         return(PL);
  230.     return(UNKNOWN);
  231. }
  232.  
  233. /* GetAgVal - get argument value */
  234. GetArgVal(line, argtyp)
  235. char *line;
  236. int  *argtyp;
  237. {
  238.     while (!isspace(*line))
  239.         line++;
  240.     while (*line == ' ' || *line == '\t')
  241.         line++;
  242.     *argtyp = *line;
  243.     if (*line == PLUS || *line == MINUS)
  244.         line++;
  245.     return(atoi(line));
  246. }
  247.  
  248. /* set - set parameter and check range */
  249. set(param, val, argtyp, defval, minval, maxval)
  250. int    *param;
  251. int    val,argtyp,defval,minval,maxval;
  252. {
  253.     if (argtyp == '\n')
  254.         *param = defval;
  255.     else if (argtyp == PLUS)
  256.         *param += val;
  257.     else if (argtyp == MINUS)
  258.         *param -= val;
  259.     else
  260.         *param = val;
  261.     *param = min(*param, maxval);
  262.     return max(*param, minval);
  263. }
  264.  
  265. /* Text - process text lines */
  266. void Text(line)
  267. char *line;
  268. {
  269. char wrdbuf[INSIZE];
  270. int  i;
  271.     i = 0;
  272.     if (isspace(*line))
  273.         LeadBlank(line);
  274.     if (ceval > 0) {
  275.         tival = max((rmval + tival - width(line))/2, 0);
  276.         put(line);
  277.         ceval--;
  278.         }
  279.     else if (*line == '\n')
  280.         put(line);
  281.     else if (fill == NO)    
  282.         put(line);
  283.     else
  284.         while (GetWord(line, &i, wrdbuf) > 0)
  285.             PutWord(wrdbuf);
  286. }
  287.  
  288. /* put - put out line with proper spacing andindenting */
  289. void put(line)
  290. char *line;
  291. {
  292. int    i;
  293.     if (lineno == 0 || lineno > bottom)
  294.         phead();
  295.     for (i = 0; i < tival; i++)
  296.         putchar(' ');
  297.     tival = inval;
  298.     puts(line);
  299.     skip(min(lsval-1, bottom - lineno));
  300.     lineno += lsval;
  301.     if (lineno > bottom)
  302.         pfoot();
  303. }
  304.  
  305. void LineSpace(i)
  306. int    i;
  307. {
  308.     brk();
  309.     if (lineno > bottom)
  310.         return;
  311.     if (lineno == 0)
  312.         phead();
  313.     skip(min(i,bottom + 1 - lineno));
  314.     lineno += i;
  315.     if (lineno > bottom)
  316.         pfoot();
  317. }
  318.  
  319. /* phead - put out line with proper spacing and indenting */
  320. void phead()
  321. {
  322.     curpag = newpag++;
  323.     if (m1val > 0) {
  324.         skip(m1val-1);
  325.         PutTitle(header, curpag);
  326.         }
  327.     skip(m2val);
  328.     lineno = m1val + m2val + 1;
  329. }
  330.  
  331. /* pfoot - put out page footer */
  332. void pfoot()
  333. {
  334.     skip(m3val);
  335.     if (m4val > 0) {
  336.         PutTitle(footer, curpag);
  337.         skip(m4val-1);
  338.         }
  339. }
  340.  
  341.  
  342. /* PutTitle - put out title line with optional pagenumber */
  343. void PutTitle(line, pageno)
  344. char    *line;
  345. int    pageno;
  346. {
  347.     *line--;
  348.     while (*++line)
  349.         if (*line == PAGENUM)
  350.             printf("%3d", pageno);
  351.         else
  352.             putchar(*line);
  353. }
  354.  
  355. /* skip - output n blank lines */
  356. void skip(i)
  357. int    i;
  358. {
  359.     while (i--)
  360.         putchar('\n');
  361. }
  362.  
  363. void LeadBlank(buf)
  364. char *buf;
  365. {
  366. char *temp;
  367. int  i;
  368.     temp = buf;
  369.     i = 0;
  370. /*
  371.     brk();
  372. */
  373.     while (*buf == ' ' || *buf == '\t') {
  374.         if (*buf++ == '\t')
  375.             i = (i & ~0x07) + 8;
  376.         else
  377.             i++;
  378.         }
  379.     if (*buf != '\n' && fill == NO)
  380.         tival = i;
  381.     while (*buf)
  382.         *temp++ = *buf++;
  383.     *temp = NULL;
  384. }
  385.  
  386. GetWord(in, ii, out)
  387. char in[], *out;
  388. int  *ii;
  389. {
  390. int i;
  391. char *p;
  392.     p = out;
  393.     i = *ii;
  394.     while (in[i] == ' ' || in[i] == '\t')
  395.         i++;
  396.     while (in[i] && !isspace(in[i]))
  397.         *out++ = in[i++];
  398.     *out = '\0';
  399.     *ii = i;
  400.     return(out - p);
  401. }
  402.  
  403. void PutWord(wrdbuf)
  404. char *wrdbuf;
  405. {
  406. int last, llval, nextra, w;
  407.     w = width(wrdbuf);
  408.     last = strlen(wrdbuf) + outp + 1;
  409.     llval = rmval - tival;
  410.     if (outp > 0 && (outw + w > llval || last >= MAXOUT)) {
  411.         last -= outp;
  412.         nextra = llval - outp + 1;
  413.         spread(outbuf, outp, nextra, outwds);
  414.         if (nextra > 0 && outwds > 1)
  415.             outp += nextra;
  416.         brk();
  417.         }
  418.     strcpy(outbuf+outp+1, wrdbuf);
  419.     outp = last;
  420.     outbuf[outp] = BLANK;
  421.     outw += w + 1;
  422.     outwds++;
  423. }
  424.  
  425. /* brk - end current filled line */
  426. void brk()
  427. {
  428.     if (outp > 0) {
  429.         outbuf[outp] = '\n';
  430.         outbuf[outp+1] = '\0';
  431.         put(outbuf+1);
  432.         }
  433.     outp = 0;
  434.     outw = 0;
  435.     outwds = 0;
  436. }
  437.  
  438. /* width - compute width of character string */
  439. width(buf)
  440. char *buf;
  441. {
  442. int w;
  443.     w = 0;
  444.     for ( ;*buf != EOS; *buf++)
  445.         if (*buf == BACKSPACE)
  446.             w--;
  447.         else if (*buf != '\n')
  448.             w++;
  449.     return(w);
  450. }
  451.  
  452. /* spread - spread words to justify  right margin */
  453. void spread(buf, outp, nextra, outwds)
  454. char *buf;
  455. int    outp,nextra,outwds;
  456. {
  457. int i, j, nb, ne, nholes;
  458.     if (nextra <= 0 || outwds <= 1)
  459.         return;
  460.     dir = 1 - dir;
  461.     ne = nextra;
  462.     nholes = outwds - 1;
  463.     i = outp - 1;
  464.     j = min(MAXOUT-2, i + ne);
  465.     while (i < j) {
  466.         buf[j] = buf[i];
  467.         if (buf[i] == ' ') {
  468.             if (dir == 0)
  469.                 nb = (ne - 1) / nholes + 1;
  470.             else
  471.                 nb = ne / nholes;
  472.             ne = ne - nb;
  473.             nholes = nholes - 1;
  474.             for (; nb > 0; nb--) {
  475.                 j--;
  476.                 buf[j] = ' ';
  477.                 }
  478.             }
  479.         i--;
  480.         j--;
  481.         }
  482.     return;
  483. }
  484.  
  485. void GetTitle(line, title)
  486. char *line, *title;
  487. {
  488.     while (!isspace(*line)) line++;
  489.     while (*line == ' ' || *line == '\t') line++;
  490.     if (*line == SQUOTE || *line == DQUOTE)
  491.         line++;
  492.     strcpy(title, line);
  493. }
  494.  
  495. void init()
  496. {
  497.     fill  = YES;    /* fill if YES; init = YES            */
  498.     lsval = 1;    /* current line spacing; init = 1        */
  499.     inval = 0;    /* current indent; >= 0; init = 0        */
  500.     rmval = 60;    /* current right margin; init = PAGEWIDTH = 60    */
  501.     tival = 0;    /* current temporary indent; init = 0        */
  502.     ceval = 0;    /* # of lines to center; init = 0        */
  503.     ulval = 0;    /* # of lines to underline; init = 0        */
  504.     curpag = 0;
  505.     newpag = 1;
  506.     lineno = 0;
  507.     plval  = 66;
  508.  
  509.     m1val  = 2;
  510.     m2val  = 1;
  511.     m3val  = 1;
  512.     m4val  = 2;
  513.     bottom = plval - m3val - m4val;
  514.     header = __header;
  515.     *header++ = '\n';  *header-- = '\0';
  516.     footer = __footer;
  517.     *footer++ = '\n';  *footer-- = '\0';
  518.  
  519.     outp = 0;
  520.     outw = 0;
  521.     outwds = 0;
  522.     dir = 0;
  523. }
  524.